/* **********************************************************************************
 * Copyright (c) 2011 John Hughes
 *
 * Elve Touch is licenced under the Microsoft Reciprocal License (Ms-RL).
 *
 * Project Website: http://elvetouch.codeplex.com/
 * **********************************************************************************/

using System;


namespace ElveTouch
{
    public static class SystemUtility
    {

        public static byte CalculateByteChecksum(byte[] b)
        {
            return CalculateByteChecksum(b, 0, b.Length);
        }

        public static byte CalculateByteChecksum(byte[] b, int startIndex, int length)
        {
            // Returns byte checksum. This is the two's complement of
            // the modulo-8bit sum of the byte array.

            long sum = 0;
            for (int i = startIndex; i < startIndex + length; i++)
                sum += (long)b[i];

            sum = -(sum % (0xFF + 1));

            return (byte)sum;
        }



        public static UInt32 CalculateUInt32Checksum(byte[] b)
        {
            return CalculateUInt32Checksum(b, 0, b.Length);
        }

        public static UInt32 CalculateUInt32Checksum(byte[] b, int startIndex, int length)
        {
            // Returns UInt32 checksum. This is the two's complement of
            // the modulo-32bit sum of the byte array.

            long sum = 0;
            for (int i = startIndex; i < startIndex + length; i++)
                sum += (long)b[i];

            sum = -(sum % (0xFFFF + 1));

            return (UInt32)sum;
        }


        public static byte[] ConcatenateByteArrays(params byte[][] arrays)
        {
            // See: http://stackoverflow.com/questions/415291/best-way-to-combine-2-or-more-byte-arrays-in-c

            //byte[] rv = new byte[arrays.Sum(a => a.Length)]; // require linq
            int length = 0;
            foreach (byte[] b in arrays)
                length += b.Length;
            byte[] rv = new byte[length];

            int offset = 0;
            foreach (byte[] array in arrays)
            {
                System.Buffer.BlockCopy(array, 0, rv, offset, array.Length);
                offset += array.Length;
            }
            return rv;
        }

    }
}
